package com.david.fastmsg.controller;

import com.david.fastmsg.enums.ResponseEnum;
import com.david.fastmsg.exception.RespException;
import com.david.fastmsg.service.FileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;

@Controller
@RequestMapping(value = "/file")
public class FileController {

    @Autowired
    private FileService fileService;

    /**
     * <pre>
     *
     * 接口功能： 文件上传接口
     *
     * 接口路径： /file/upload
     *
     * 接口描述： 上传文件接口，通过判断上传文件的文件后缀名，为上传的文件分发到不同的文件存储位置，
     * 如果是图片文件，会返回图片的预览地址，如果是其他文件，返回文件的下载地址
     * 返回的文件地址部分内容被加密
     *
     * 输入参数：
     * file                      |MultipartFile|M| 文件
     *
     * 输出参数：
     * respCode                       |String|M| 返回码
     * respMsg                        |String|M| 返回描述
     * previewPath                    |String|O| 图片预览地址
     * downloadPath                   |String|O| 文件下载地址
     * fileType                       |String|M| 文件类型， pic|other
     * </pre>
     * @param file
     * @return
     */
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @ResponseBody
    public Map upload(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            throw new RespException(ResponseEnum.ERR_CTL_FILE_NOT_EXISTS);
        }
        return fileService.upload(file);
    }


    /**
     * <pre>
     *
     * 接口功能： 文件预览接口
     *
     * 接口路径： /file/preview/{fileName}
     *
     * 接口描述： 解析加密的文件名，读取文件，返回图片流
     *
     * 输入参数：
     * fileName                      |String|M| 文件名
     *
     * 输出参数：
     * </pre>
     * 获取图片
     * @param response
     * @throws IOException
     */
    @RequestMapping(value = "/preview/{fileName}",method= RequestMethod.GET)
    public void preview(@PathVariable @NotNull String fileName, HttpServletResponse response)
            throws IOException {
        InputStream in = null;
        ServletOutputStream sos = null;
        try {
            File file = fileService.preview(fileName);
            in = new FileInputStream(file);
            sos = response.getOutputStream();
            byte[] b = new byte[1024];
            while (in.read(b) != -1) {
                sos.write(b);
            }
            sos.flush();
        } catch (Exception ex) {
            throw new RespException(ResponseEnum.ERR_CTL_FILE_PREVIEW_FAIL);
        } finally {
            if (in != null) {
                in.close();
            }
            if (sos != null) {
                sos.close();
            }
        }

    }


    /**
     * <pre>
     *
     * 接口功能： 文件下载接口
     *
     * 接口路径： /file/download/{fileName}
     *
     * 接口描述： 解析加密的文件名，读取文件，推送到浏览器下载
     *
     * 输入参数：
     * fileName                      |String|M| 文件名
     *
     * 输出参数：
     * </pre>
     * 下载
     * @param response
     * @throws IOException
     */
    @RequestMapping(value = "/download/{fileName}",method= RequestMethod.GET)
    public void download(@PathVariable @NotNull String fileName, HttpServletResponse response)
            throws IOException {
        InputStream in = null;
        OutputStream os = null;
        File file = fileService.preview(fileName);
        try {
            System.out.println("文件名称：" + file.getName());
            in = new BufferedInputStream(new FileInputStream(file));
            byte[] buffer = new byte[in.available()];
            in.read(buffer);
            response.reset();
            response.addHeader("Content-Disposition","attachment;filename=" + file.getName());
            response.addHeader("Content-Length", ""+ file.length());
            response.setCharacterEncoding("utf-8");
            os = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            os.write(buffer);
            os.flush();

        } catch (Exception ex) {
            throw new RespException(ResponseEnum.ERR_CTL_FILE_DOWNLOAD_FAIL);
        } finally {
            if (in != null) {
                in.close();
            }
            if (os != null) {
                os.close();
            }
        }

    }
}
